#include "unoboardentity.h"
#include <QStyleOptionGraphicsItem>
#include "../aurasim.h"

UnoBoardEntity::UnoBoardEntity(QGraphicsItem *parent):
    Entity (parent)
{
    setName("UnoBoard");
    setFlags(ItemIsSelectable | ItemIsMovable);

    mBoardImg = QImage(":/icons/icon_uno.png");
    mBoardImg = mBoardImg.scaled(680, mBoardImg.height() * 680 / mBoardImg.width(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
    mBoardSize = mBoardImg.size();
    mDrawImg = mBoardImg;
    setCanRemove(false);

    QList<QPointF> poses;
    poses << QPointF(292.0, - 219.5)
          << QPointF(269.0, - 219.5)
          << QPointF(246.0, - 219.5)
          << QPointF(223.0, - 219.5)
          << QPointF(200.8, - 219.5)
          << QPointF(177.6, - 219.5)
          << QPointF(154.2, - 219.5)
          << QPointF(131.5, - 219.5)
          << QPointF(94.5, - 219.5)
          << QPointF(71.3, - 219.5)
          << QPointF(47.8, - 219.5)
          << QPointF(25.0, - 219.5)
          << QPointF(2.3, - 219.5)
          << QPointF(-20.4, - 219.5)
          << QPointF(177.8, 218.6)
          << QPointF(200.9, 218.6)
          << QPointF(224.4, 218.6)
          << QPointF(246.4, 218.6)
          << QPointF(269.5, 218.6)
          << QPointF(292.6, 218.6);


    for(int i = 0; i < 20; i++) {
        QSharedPointer<PinEntity> pin(new PinEntity(this));
        pin->setPinMode(1);
        if(i < 14)
            pin->setPinDirection(PinDirection::Up);
        else
            pin->setPinDirection(PinDirection::Down);
        pin->setPos(poses.at(i));
        Aurasim::entityManager()->addSubEntity(pin.data());
        mPins.append(pin);
    }

    setZValue(0);
}

QRectF UnoBoardEntity::boundingRect() const
{
    return QRectF(-mBoardSize.width() / 2, -mBoardSize.height() / 2, mBoardSize.width(), mBoardSize.height());
}

void UnoBoardEntity::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(widget)

    QColor drawColor(255, 255, 255);
    QPen pen;
    pen.setColor(drawColor);
    painter->setPen(pen);
    if(option->state & QStyle::State_MouseOver) {
        painter->drawRect(boundingRect());
    }

    if(option->state & QStyle::State_Selected) {
        drawColor = QColor(255, 255, 189);
        pen.setColor(drawColor);
        painter->setPen(pen);
        painter->drawRect(boundingRect());
    }
    painter->drawImage(boundingRect(), mDrawImg);
}

void UnoBoardEntity::start()
{
    mArduino.start();
}

void UnoBoardEntity::stop()
{
    mArduino.stop();
}

void UnoBoardEntity::tick(const int &ms)
{
    mArduino.tick(ms);

    if(!mArduino.isSimulating()){
        foreach (const QSharedPointer<PinEntity>& pin, mPins) {
            pin->setPinVal(0);
        }
        return;
    }
    const QList<int>& pinModeVals = mArduino.pinModVals();
#pragma omp parallel for num_threads(6)
    for(int i = 0; i < pinModeVals.count(); i++) {
        mPins.at(i)->setPinMode(pinModeVals[i]);
    }


    const QList<int>& pinVals = mArduino.pinVals();
    const QList<int>& signalTypes = mArduino.signalTypes();

#pragma omp parallel for num_threads(6)
    for(int i = 0; i < pinVals.count(); i++) {
        mPins.at(i)->setPinVal(pinVals[i]);
        qreal volt = signalTypes[i] == 0 ? pinVals[i] * 3.3 : pinVals[i] * 1.0 / 255 * 3.3;
        mPins.at(i)->setVolt(volt);
    }
}
